#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <pthread.h>
#include <ctype.h>

void err(char *msg,int exitCode){
    perror(msg);
    if(exitCode == 0){
        return;
    }
    exit(1);
}


char *strupr(char *str)
{
    char *orign=str;
    for (; *str!='\0'; str++)
        *str = toupper(*str);
    return orign;
}


void *tfn(void *arg){
    int client_fd = (int)arg;
    char buf[10];//传输的数据
    int maxDataSize = 10;
    if(recv(client_fd,buf,maxDataSize,0) == -1) {//接收客户端的请求
        err("recv",1);
    }
    printf("%lu received a connection : %s\n",pthread_self(),buf);
    char *res = strupr(buf);
    write(client_fd,res, strlen(res));
    close(client_fd);
    return NULL;
}


int main(){
    struct sockaddr_in server_sockaddr,client_sockaddr;
    int s_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (s_fd == -1){
        err("socket",1);
    }

    //以sockaddt_in结构体填充socket信息
    server_sockaddr.sin_family = AF_INET;//IPv4
    server_sockaddr.sin_port = htons(7777);//端口
    server_sockaddr.sin_addr.s_addr = INADDR_ANY;//本主机的任意IP都可以使用
    bzero(&(server_sockaddr.sin_zero),8);//填充0

    int ret;
    ret = bind(s_fd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr));
    if (ret == -1){
        err("bind",1);
    }
    printf("bind success!\n");

    //请求队列中允许的最大请求数量设置为5
    ret  = listen(s_fd,5);
    if (ret == -1){
        err("listen",1);
    }
    printf("listen success!\n");

    socklen_t len = sizeof(client_sockaddr);
    while (1){
        int client_fd = accept(s_fd, (struct sockaddr *)&client_sockaddr, &len);
        if(ret == -1){
            err("accept",0);
            continue;
        }
        printf("accept success!\n");

        pthread_t tid;
        ret = pthread_create(&tid,NULL,tfn,(void *)client_fd);
        if (ret == -1){
            err("pthread_create",0);
            continue;
        }
        ret = pthread_detach(ret);
        if (ret == -1){
            err("pthread_detach",1);
        }
    }
    close(s_fd);
}
